﻿using System;
using System.Windows.Controls;
using System.Windows;
using System.Net;

namespace AccessControl.Wpf.Controls
{
	class IpControl : Control
	{
		#region Fields

		TextBox[] _textBoxes;
		bool _isChanging = false;
		private static readonly Type s_ThisType = typeof(IpControl);

		#endregion

		#region Static Constructor

		static IpControl()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(IpControl), new FrameworkPropertyMetadata(typeof(IpControl)));
		}

		#endregion

		#region Dependency Properties

		public static readonly DependencyProperty IpProperty = DependencyProperty.Register(
			"IP",
			typeof(IPAddress),
			s_ThisType,
			new PropertyMetadata(null, OnIpAddressChanged));

		#endregion

		#region Public Properties
		
		public IPAddress IP
		{
			get { return (IPAddress)GetValue(IpProperty); }
			set { SetValue(IpProperty, value); }
		}

		#endregion

		#region Overrides

		public override void OnApplyTemplate()
		{
			/* First the base */
			base.OnApplyTemplate();
			
			/* Now apply to the text events */
			_textBoxes = new TextBox[4];
			_textBoxes[0] = Template.FindName("_txt1", this) as TextBox;			
			_textBoxes[1] = Template.FindName("_txt2", this) as TextBox;
			_textBoxes[2] = Template.FindName("_txt3", this) as TextBox;
			_textBoxes[3] = Template.FindName("_txt4", this) as TextBox;

			foreach (TextBox txt in _textBoxes)
			{
				txt.TextInput += (OnTextBoxTextInput);
				txt.TextChanged += (OnTextChanged);
			}

			UpdateIpAddressToTextBoxes();
		}

		void OnTextBoxTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
		{
			int n;

			if (!int.TryParse(e.Text, out n))
				e.Handled = true;
		}

		#endregion

		#region Private Members

		private void OnTextChanged(object sender, TextChangedEventArgs e)
		{
			IPAddress ipAddress;
			string ip = string.Empty;
			bool bIsValidString = true;
			TextBox txt = (TextBox)sender;

			if (_isChanging)
				return;

			foreach (TextChange textChange in e.Changes)
			{
				if (textChange.AddedLength > 0)
				{
					string sChange = txt.Text.Substring(textChange.Offset, textChange.AddedLength);
					foreach (char c in sChange)
					{
						if (!char.IsDigit(c))
						{
							bIsValidString = false;
							break;
						}
					}

					if (!bIsValidString)
					{
						txt.Text = txt.Text.Remove(textChange.Offset, textChange.AddedLength);
						txt.SelectionStart = txt.Text.Length;
						return;
					}
				}
			}

			ip = string.Format("{0}.{1}.{2}.{3}", _textBoxes[0].Text, _textBoxes[1].Text, _textBoxes[2].Text, _textBoxes[3].Text);

			if (IPAddress.TryParse(ip, out ipAddress))
			{
				_isChanging = true;
				this.IP = ipAddress;
				_isChanging = false;
			}
		}

		private static void OnIpAddressChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
		{
			((IpControl)o).UpdateIpAddressToTextBoxes();
		}

		private void UpdateIpAddressToTextBoxes()
		{
			if (_textBoxes != null)
			{
				_isChanging = true;
				
				if (IP != null)
				{
					string ipAddress = IP.ToString();
					string[] parts = ipAddress.Split('.');
					for (int i = 0; i < parts.Length; ++i)
					{
						if (_textBoxes[i] != null)
							_textBoxes[i].Text = parts[i];
					}
				}
				else
				{
					for (int i = 0; i < 4; ++i)
						_textBoxes[i].Text = string.Empty;
				}
				
				_isChanging = false;
			}
		}

		#endregion
	}
}
